package org.fast.develop.logicflow.management.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.fast.develop.logicflow.management.bo.LogicBytearrayBo;
import org.fast.develop.logicflow.management.bo.LogicModelBo;
import org.fast.develop.logicflow.management.bo.LogicModelDetailBo;
import org.fast.develop.logicflow.management.builder.CreateDeploymentBuilder;
import org.fast.develop.logicflow.management.builder.CreateModelBuilder;
import org.fast.develop.logicflow.management.builder.UpdateModelBuilder;
import org.fast.develop.logicflow.management.exception.LogicException;
import org.fast.develop.logicflow.repository.domain.bytearray.LogicBytearray;
import org.fast.develop.logicflow.repository.domain.bytearray.LogicBytearrayRepository;
import org.fast.develop.logicflow.repository.domain.deployment.LogicDeployment;
import org.fast.develop.logicflow.repository.domain.model.LogicModel;
import org.fast.develop.logicflow.repository.domain.model.LogicModelRepository;
import org.fast.develop.logicflow.management.service.LogicModelService;
import org.fast.develop.logicflow.management.service.LogicRepositoryService;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author 莫寅
 * @createTime 2022-12-20 01:09
 * @desc：
 */
public class ModelServiceImpl implements LogicModelService {

    private LogicModelRepository logicModelRepository;
    private LogicBytearrayRepository logicBytearrayRepository;
    private LogicRepositoryService repositoryService;

    public ModelServiceImpl(LogicModelRepository logicModelRepository, LogicBytearrayRepository logicBytearrayRepository, LogicRepositoryService repositoryService) {
        this.logicModelRepository = logicModelRepository;
        this.logicBytearrayRepository = logicBytearrayRepository;
        this.repositoryService = repositoryService;
    }

    @Override
    public LogicModelDetailBo get(String modelId) {
        LogicModel logicModel = logicModelRepository.get(modelId);
        LogicModelDetailBo logicModelDetailBo = BeanUtil.copyProperties(logicModel, LogicModelDetailBo.class);
        if(logicModel.getResourceId() != null){
            LogicBytearray logicBytearray = logicBytearrayRepository.get(logicModel.getResourceId());
            String schema = new String(logicBytearray.getBytes());
            logicModelDetailBo.setSchema(schema);
        }

        return logicModelDetailBo;
    }

    @Override
    public String getSchema(String modelId) {
        LogicModel logicModel = logicModelRepository.get(modelId);
        if(StrUtil.isBlank(logicModel.getResourceId())){
            return null;
        }
        LogicBytearray logicBytearray = logicBytearrayRepository.get(logicModel.getResourceId());
        return StrUtil.utf8Str(logicBytearray.getBytes());
    }

    @Override
    public void saveSchema(String modelId, String schema) {
        LogicModel logicModel = logicModelRepository.get(modelId);
        LogicBytearray logicBytearray = null;

        //是否已经存在资源ID,没有则新增，有则修改
        if(logicModel.getResourceId() == null){
            String bytearrayName = logicModel.getKey() + "_" + logicModel.getName() + ".json";
            //创建文件
            LogicBytearrayBo logicBytearrayBo = new LogicBytearrayBo();
            logicBytearrayBo.setName(bytearrayName);
            logicBytearrayBo.setBytes(schema.getBytes());
            logicBytearray = logicBytearrayRepository.save(logicBytearrayBo);
        }else{
            logicBytearray = logicBytearrayRepository.get(logicModel.getResourceId());
            LogicBytearrayBo getLogicBytearrayBo = BeanUtil.copyProperties(logicBytearray, LogicBytearrayBo.class);
            getLogicBytearrayBo.setBytes(schema.getBytes());
            logicBytearray =logicBytearrayRepository.save(getLogicBytearrayBo);
        }


        LogicModelBo logicModelBo = BeanUtil.copyProperties(logicModel, LogicModelBo.class);
        logicModelBo.setResourceId(logicBytearray.getId());
        logicModelRepository.save(logicModelBo);

    }


    @Override
    public List<? extends LogicModel> getList(LogicModel logicModel) {
        return logicModelRepository.getList(logicModel);
    }

    @Override
    public CreateModelBuilder createModel() {
        return new CreateModelBuilder(this);
    }

    @Override
    public LogicModel create(CreateModelBuilder createModelBuilder) {
        LogicModelBo logicModelBo = new LogicModelBo();

        //创建模型表
        if(StrUtil.isNotBlank(createModelBuilder.getCategory())){
            logicModelBo.setCategory(createModelBuilder.getCategory());
        }
        if(StrUtil.isNotBlank(createModelBuilder.getKey())){
            logicModelBo.setKey(createModelBuilder.getKey());
        }
        if(StrUtil.isNotBlank(createModelBuilder.getName())){
            logicModelBo.setName(createModelBuilder.getName());
        }
        logicModelBo.setCreateTime(new Date());
        logicModelBo.setVersion(1);
        return logicModelRepository.save(logicModelBo);
    }

    @Override
    public UpdateModelBuilder updateModel() {
        return new UpdateModelBuilder(this);
    }


    @Override
    public LogicModel update(UpdateModelBuilder updateModelBuilder) {
        Assert.notNull(updateModelBuilder.getId(), "id is not be null");

        LogicModel logicModel = logicModelRepository.get(updateModelBuilder.getId());
        LogicModelBo logicModelBo = BeanUtil.copyProperties(logicModel, LogicModelBo.class);

        //创建模型表
        logicModelBo.setId(updateModelBuilder.getId());
        if(StrUtil.isNotBlank(updateModelBuilder.getCategory())){
            logicModelBo.setCategory(updateModelBuilder.getCategory());
        }
        if(StrUtil.isNotBlank(updateModelBuilder.getKey())){
            logicModelBo.setKey(updateModelBuilder.getKey());
        }
        if(StrUtil.isNotBlank(updateModelBuilder.getName())){
            logicModelBo.setName(updateModelBuilder.getName());
        }

        logicModelBo.setLastUpdateTime(new Date());
        return logicModelRepository.save(logicModelBo);
    }


    @Override
    public LogicDeployment deploy(String modelId) {
        LogicModel logicModel = logicModelRepository.get(modelId);

        LogicDeployment logicDeployment = new CreateDeploymentBuilder(repositoryService)
                .name(logicModel.getName())
                .key(logicModel.getKey())
                .category(logicModel.getCategory())
                .modelId(modelId)
                .deploy();
        return logicDeployment;
    }


    @Override
    public void delete(String modelId) {
        logicModelRepository.delete(modelId);
    }

}
